iT邦幫忙

2022 iThome 鐵人賽

DAY 29
0

細節補充

一、邊界條件

在過去幾天,我在文章中曾不只一次提到過邊界條件,第一次我只概略地說,我認為那是極端條件。雖然這個解釋不能算錯,然而隨著持續閱讀書中內容,我想稍微補充一下關於邊界條件的概念。

在程式功能的極盡之處,我們會需要多加一些條件判斷,好讓所撰寫的內容仍然可以正常運行,而這個條件,就稱之為邊界條件。例如分頁的判斷,就是一個很常遇到與撰寫的邊界條件。

const pagination = {
  total: 10,
  current: 1,
};

const next = () => {
  if (pagination.current < pagination.total) {
    pagination.current++;
  }
};

上面是一個簡單的例子,當分頁到了最後一頁就無法再向後,是以我們會在當中加入判斷條件,避免程式出現錯誤。

二、函式內容應該下降抽象層次一層

在函式裡的敘述,都應該要撰寫在同樣的抽象層次上。這個層次應該比函式名稱所描述的抽象行為還低一個抽象層次。

函式的撰寫原則不難,但往往撰寫時仍會將不同層次的抽象概念混合,所以想補充、分享一個從混合到分離的例子,增加我們對於函式內容的敏感度。

public String render () throws Exception
{
    StringBuffer html = new StringBuffer("<hr");
    if(size > 0)
        html.append(" size=\"").append(size + 1).append("\"");
    html.append(">");

    return html.toString();
}

這是一個來自 FitNesse 的範例。該函式會創建一個水平線標籤 ( hr ) ,並且這個水平線會隨著變數 size 去做粗細的調整。而這個函式至少包含兩個抽象概念,一個是 hr 標籤本身,另一個則是水平線的粗細。

我們可能會想讓程式碼的意圖與表達力更清晰一些,而對該函式進行重構:

public String render () throws Exception
{
    HtmlTag hr = new HtmlTag("hr");
    if(size > 0)
        hr.addAttribute("size", "" + (size + 1));

    return hr.html();
}

作者成功地將函式的抽象層次劃分開,可讀性也順利提升,但結果是,該函式仍然包含著不同層次的概念,所以再次對它進行調整:

public String render () throws Exception
{
    HtmlTag hr = new HtmlTag("hr");
    if(extraDashes > 0)
        hr.addAttribute("size", hrSize(extraDashes));
    return hr.html();
}

private String hrSize (int height)
{
    int hrSize = height + 1;
    return String.format("%d", hrSize);
}

兩個抽象概念被分別劃分至不同的函式中,保持函式遵循「只做一件事」的原則,並且將 size 真正的意圖凸顯出來 ──── 額外破折號的數量。至此順利完成了重構,將不同的概念分離開,使程式碼變得更加容易閱讀與理解。


上一篇
異味(九):測試篇
下一篇
總結
系列文
重新開始學程式,【無瑕的程式碼:敏捷軟體開發技巧守則】共讀30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言